package edu.sias.hyznxfapi.chat.imgCreateIme;

import com.google.gson.Gson;
import com.google.gson.JsonObject;
import com.google.gson.JsonParser;

import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
import java.io.*;
import java.net.HttpURLConnection;
import java.net.URI;
import java.net.URL;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.text.SimpleDateFormat;
import java.util.*;
public class ImgToImg {

    /**
     * 图生图--尚未完善
     */
        private static final String APP_ID = "9a6acf89";
        private static final String CREATE_HOST_URL = "https://cn-huadong-1.xf-yun.com/v1/private/s3fd61810/create";
        private static final String QUERY_HOST_URL = "https://cn-huadong-1.xf-yun.com/v1/private/s3fd61810/query";
        private static final String API_KEY = "dcf541522637a46bd1870bd9c29a00a3";
        private static final String API_SECRET = "YTUzNTU4NGVhYjViNjY3ZTUwZTk4ODhm";

        public static void main(String[] args) throws Exception {

            // 读取图像文件的字节数据

            //图片路径
            String imagePath = "D:/11/存储/xf_image.jpg";
            String imageData = encodeImageToBase64(imagePath);


            // 输出 Base64 字符串
            System.out.println(imageData);
            String taskID = createTask(imageData);
            System.out.println("Task ID: " + taskID);

            // Query task result
            while (true) {
                System.out.println(new Date());
                JsonObject res = queryTask(taskID);
                int code = res.get("header").getAsJsonObject().get("code").getAsInt();
                String taskStatus = "";
                if (code == 0) {
                    taskStatus = res.get("header").getAsJsonObject().get("task_status").getAsString();
                    if (taskStatus.isEmpty()) {
                        System.out.println("查询任务状态有误，请检查");
                    } else if ("3".equals(taskStatus)) {
                        System.out.println(new Date());
                        System.out.println("任务完成");
                        System.out.println(res);
                        String fText = res.get("payload").getAsJsonObject().get("result").getAsJsonObject().get("text").getAsString();
                        System.out.println("图片信息：\n" + new String(Base64.getDecoder().decode(fText), StandardCharsets.UTF_8));
                        break;
                    } else {
                        System.out.println("查询任务中：......" + res);
                        Thread.sleep(1000);
                    }
                } else {
                    System.out.println(res);
                    break;
                }
            }
        }

        // 将图片文件转换为Base64字符串
        private static String encodeImageToBase64(String imagePath) throws IOException {
            File file = new File(imagePath);
            byte[] imageData = new byte[(int) file.length()];
            FileInputStream fileInputStream = new FileInputStream(file);
            fileInputStream.read(imageData);
            fileInputStream.close();
            return Base64.getEncoder().encodeToString(imageData);
        }

        public static String createTask(String image) throws Exception {
            ArrayList<String> imageDataList = new ArrayList<>();
            imageDataList.add(image);
            Map<String, Object> text = new HashMap<>();
            text.put("image", imageDataList); // 引擎上传的原图，如果仅用图片生成能力，该字段需为空
            text.put("prompt", "精美文案"); // 该prompt 可以是要求引擎生成的描述，也可以结合上传的图片要求模型修改原图
            text.put("aspect_ratio", "1:1");
            text.put("negative_prompt", "");
            text.put("img_count", 4);
            text.put("resolution", "2k");

            String bText = "";
            try {
                bText = Base64.getEncoder().encodeToString(new Gson().toJson(text).getBytes("utf-8"));
            } catch (UnsupportedEncodingException e) {
                e.printStackTrace();
            }

            String requestUrl = createUrl(CREATE_HOST_URL);
            String data = genCreateRequestData(bText);
            Map<String, String> headers = getHeaders(CREATE_HOST_URL);

            // Logging request details
            System.out.println("Request URL: " + requestUrl);
            System.out.println("Request Headers: " + headers);
            System.out.println("Request Body: " + data);

            String response = postRequest(requestUrl, data, headers);
            System.out.println("onMessage：\n" + response);

            // Parsing response to get task ID
            JsonObject resp = JsonParser.parseString(response).getAsJsonObject();
            System.out.println(resp);
            String taskID = resp.get("header").getAsJsonObject().get("task_id").getAsString();
            System.out.println(taskID);
            return taskID;
        }

        public static JsonObject queryTask(String taskID) throws Exception {
            Map<String, Object> data = new HashMap<>();
            Map<String, String> header = new HashMap<>();
            header.put("task_id", taskID);
            header.put("app_id", APP_ID);
            data.put("header", header);


            String requestUrl = createUrl(QUERY_HOST_URL);
            String jsonData = new Gson().toJson(data);
            Map<String, String> headers = getHeaders(QUERY_HOST_URL);

            // Logging request details
            System.out.println("Request URL: " + requestUrl);
            System.out.println("Request Headers: " + headers);
            System.out.println("Request Body: " + jsonData);

            String response = postRequest(requestUrl, jsonData, headers);

            return JsonParser.parseString(response).getAsJsonObject();
        }

        public static String createUrl(String url) throws Exception {
            URI uri = new URI(url);
            String host = uri.getHost();
            String path = uri.getPath();

            // 生成RFC1123格式的时间戳
            SimpleDateFormat dateFormat = new SimpleDateFormat(
                    "EEE, dd MMM yyyy HH:mm:ss 'GMT'", Locale.US);
            dateFormat.setTimeZone(TimeZone.getTimeZone("GMT"));
            String date = dateFormat.format(new Date());

            // 拼接字符串
            String signature_origin = "host: " + host + "\n";
            signature_origin += "date: " + date + "\n";
            signature_origin += "POST " + path + " HTTP/1.1";

            // 进行hmac-sha256进行加密
            Mac sha256_HMAC = Mac.getInstance("HmacSHA256");
            SecretKeySpec secret_key = new SecretKeySpec(API_SECRET.getBytes(), "HmacSHA256");
            sha256_HMAC.init(secret_key);

            byte[] signature = sha256_HMAC.doFinal(signature_origin.getBytes("UTF-8"));

            String signature_sha_base64 = Base64.getEncoder().encodeToString(signature);

            String authorization_origin = String.format(
                    "api_key=\"%s\", algorithm=\"hmac-sha256\", headers=\"host date request-line\", signature=\"%s\"",
                    API_KEY, signature_sha_base64);

            String authorization = Base64.getEncoder().encodeToString(authorization_origin.getBytes("UTF-8"));

            // 将请求的鉴权参数组合为字典
            String v = String.format("authorization=%s&date=%s&host=%s",
                    URLEncoder.encode(authorization, "UTF-8"),
                    URLEncoder.encode(date, "UTF-8"),
                    URLEncoder.encode(host, "UTF-8"));

            // 拼接鉴权参数，生成url
            String reUrl = url + "?" + v;
            System.out.println(reUrl);
            return reUrl;
        }

        public static String genCreateRequestData(String Text) {
            return "{\"header\": {\"app_id\": \"" + APP_ID + "\", \"status\": 3, \"channel\": \"default\", \"callback_url\": \"default\"}, " +
                    "\"parameter\": {\"oig\": {\"result\": {\"encoding\": \"utf8\", \"compress\": \"raw\", \"format\": \"json\"}}}, " +
                    "\"payload\": {\"oig\": {\"text\": \"" + Text + "\"}}}";
        }

        public static Map<String, String> getHeaders(String url) {
            Map<String, String> headers = new HashMap<>();
            headers.put("content-type", "application/json");
            headers.put("host", URI.create(url).getHost());
            headers.put("app_id", APP_ID);
            return headers;
        }

        public static String postRequest(String requestUrl, String data, Map<String, String> headers) throws Exception {
            URL url = new URL(requestUrl);
            HttpURLConnection con = (HttpURLConnection) url.openConnection();
            con.setRequestMethod("POST");

            // Set request headers
            for (Map.Entry<String, String> entry : headers.entrySet()) {
                con.setRequestProperty(entry.getKey(), entry.getValue());
            }

            // Enable writing data
            con.setDoOutput(true);

            try (OutputStream os = con.getOutputStream();
                 OutputStreamWriter osw = new OutputStreamWriter(os, "utf-8")) {
                // 将数据写入输出流
                osw.write(data);
            } catch (UnsupportedEncodingException e) {
                // 当指定的字符编码不支持时的异常处理
                e.printStackTrace();
            } catch (IOException e) {
                // IO 异常处理
                e.printStackTrace();
            }

            // Read response
            StringBuilder response = new StringBuilder();
            try (BufferedReader br = new BufferedReader(new InputStreamReader(con.getInputStream(), "utf-8"))) {
                String responseLine;
                while ((responseLine = br.readLine()) != null) {
                    response.append(responseLine.trim());
                }
            }

            int responseCode = con.getResponseCode();
            if (responseCode != 200) {
                System.out.println("Error: " + responseCode + " - " + con.getResponseMessage());
                System.out.println("Response: " + response.toString());
            }

            return response.toString();
        }

}
